﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using com.kmer.Cache;

// ReSharper disable once CheckNamespace
namespace com.kmer
{
    /// <summary>
    /// 维护在线用户列表
    /// </summary>
    public static class OnlineUsers
    {
        const string CACHE_KEY = "online-users:";
        const string CACHE_KEY_CUSID = CACHE_KEY + "cusid:";
        /// <summary>
        /// 增加在线用户
        /// </summary>
        /// <param name="user"></param>
        static void AddUser(OnlineUser user)
        {
            if (HttpContext.Current == null || HttpContext.Current.Session == null) return;
            RedisCache.AddObject(CACHE_KEY_CUSID + user.CusID, user, HttpContext.Current.Session.Timeout);
        }
        /// <summary>
        /// 移除在线用户
        /// </summary>
        /// <param name="cusId"></param>
        public static void RemoveUser(int cusId = 0)
        {
            string ck_cusId = CACHE_KEY_CUSID + cusId;
            if (RedisCache.Exists(ck_cusId))
            {
                RedisCache.Remove(CACHE_KEY_CUSID + cusId);
            }
        }

        /// <summary>
        /// 用户Token
        /// </summary>
        /// <returns></returns>
        public static string GetToken(int UserID)
        {
            var guid = Guid.NewGuid();
            RedisCache.Add(guid.ToString(), UserID, 120);
            return guid.ToString();
        }

        /// <summary>
        /// 用户Token未写入redis
        /// </summary>
        /// <returns></returns>
        public static string GetUserToken(int UserID)
        {
            var guid = Guid.NewGuid();
            return guid.ToString();
        }


        /// <summary>
        /// 把当前用户添加到在线用户列表
        /// </summary>
        public static void AddAndRefresh(int UserID, string UserName)
        {
            var key = CACHE_KEY_CUSID + UserID;
            var exists = RedisCache.Exists(key);
            OnlineUser user = null;
            if (!exists)
            {
                user = new OnlineUser
                {
                    CusID = UserID,
                    LoginDate = DateTime.Now,
                    RefreshTime = DateTime.Now,
                    UserName = UserName
                };
                Log.WriteLog("登记在线用户：" + user.UserName);
            }
            else
            {
                user = RedisCache.Get<OnlineUser>(key);
                user.RefreshTime = DateTime.Now;
                Log.WriteLog("刷新在线用户：" + user.UserName);
            }
            AddUser(user);
        }
        /// <summary>
        /// 在线用户数量
        /// </summary>
        public static long Count
        {
            get { return RedisCache.Count(CACHE_KEY_CUSID + "*"); }
        }

        /// <summary>
        /// 获取在线用户列表（最近有刷新的排前）
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public static List<OnlineUser> GetUsers(int count = 10)
        {
            var userList = RedisCache.GetList<OnlineUser>(CACHE_KEY_CUSID + "*", count);
            return userList.OrderByDescending(item => item.RefreshTime).Take(count).ToList();
        }
    }
    /// <summary>
    /// 在线用户信息
    /// </summary>
    [Serializable]
    public class OnlineUser
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        public int CusID { get; set; }
        /// <summary>
        /// 微信编码
        /// </summary>
        public string OpenID { get; set; }
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; }
        /// <summary>
        /// 登陆时间
        /// </summary>
        public DateTime LoginDate { get; set; }
        /// <summary>
        /// 刷新时间
        /// </summary>
        public DateTime RefreshTime { get; set; }
        /// <summary>
        /// IP信息
        /// </summary>
        public string IPAddress { get; set; }
        /// <summary>
        /// 用户VIP等级
        /// </summary>
        public int CusType { get; set; }
        /// <summary>
        /// 在线时长
        /// </summary>
        public string OnlineTime
        {
            get
            {
                var st = DateTime.Now - this.LoginDate;
                return st.Hours > 0
                    ? string.Format("{0:D}小时{1:D}分{2:D}秒", st.Hours, st.Minutes, st.Seconds)
                    : (st.Minutes > 0
                        ? string.Format("{0:D}分{1:D}秒", st.Minutes, st.Seconds)
                        : string.Format("{0:D}秒", st.Seconds));
            }
        }
    }
}
